import Plugin from '../plugin'
import {CN,EN,Web,Cst} from '../../config'
import cssText from './index.jcss'
import ActionBar from './action.plugin.js'

export default class ImagePicker extends Plugin{
	constructor(...args){
		super(...args)
		this.name = "ImagePicker"
		this.active =true
		this.imgCache = []
		this.cfg={
			r:10
		}
		this.createClassName({
			blink:"blink",
			imgPicking:"picking-mode",
			backImgMode:"back-image-mode",
			gallary:"img-panel"
		})
		
		this.actionBar = new ActionBar(this.$event,this.$env)

		this.injectStyle(cssText,this.cn.assign({geo:Web.geo}))
		this.render()
		this.bind()
	}
	render(){
		let cn = this.cn
		this.gallary = document.createDOM("section",{
			class:cn.gallary
		})
		this.backBtn = document.createDOM("button",{
			class:cn.backImgMode+" "+CN.tip
		}) 
		this.backBtn.innerHTML = "请选择图片或者点击退出按钮"

		document.body.appendChild(this.backBtn)
		this.$event.emit(EN.layout_render,this.gallary);
	}
	bind(){
		document.addEventListener("click",(e)=>{
			if(!this.active)return
			if(!document.documentElement.classList.contains(this.cn.imgPicking))return
			e.stopImmediatePropagation()
			e.stopPropagation()
			e.preventDefault()

			if(e.target===this.backBtn)return this.onBackMode()

			let {pageX,pageY} = e
			let inPath = this.inPath(pageX,pageY)
			if(!inPath.isEmpty()){
				let img = inPath[0]
				img.classList.remove(CN.imgFocus)
				this.onBackMode(img.src)
			}
		},true)
		this.gallary.addEventListener("click",(e)=>{
			if(!this.active)return
			let t = e.target
			if(t.tagName==="IMG")
				this.$event.emit(EN.img_done,t.src)
		})
		this.gallary.addEventListener("mouseover",(e)=>{
			if(!this.active)return
			let t = e.target
			this.webPageImgToggleFocus.functional(this,t.src)

		})
		this.gallary.addEventListener("mouseout",(e)=>{
			if(!this.active)return
			this.webPageImgToggleFocus.functional(this)

		})

		document.addEventListener("mousemove",(e)=>{
			if(!this.active)return
			if(!this.webPickMode)return
			let r = this.cfg.r
			let {pageX,pageY} = e
			let img = document.querySelector("."+CN.imgFocus)
			let inPath = this.inPath(pageX,pageY)
			if(!inPath.isEmpty())
				inPath[0].classList.add(CN.imgFocus)
			img&&(img!==inPath[0])&&img.classList.remove(CN.imgFocus)
		})
		this.$event.on(EN.action,(d)=>{
			this[d.action]&&this[d.action]()
		})

		this.actionBar.on("web",this.onWebPick.bind(this))
		this.actionBar.on("gallary",this.toggleGallary.bind(this))

		this.on(Cst.focusIn,this.onFocusIn.bind(this))
		this.on(Cst.focusOut,this.onFocusOut.bind(this))
	}
	onWebPick(){
		this.webPickMode = true
		this.$event.emit(EN.action,{action:"beforeImagePick"})
		document.documentElement.classList.add(this.cn.imgPicking)
	}
	toggleGallary(data){
		if(!this.gallary.classList.contains(CN.withshow)){
			this.renderGallary()
		}
		this.gallary.classList[data.isActive?"add":"remove"](CN.withshow)
	}
	renderGallary(src){
		let imgFocus = "geo-tmp-"+Web.timestamp
		let imgStr = this.imgCache.map(img=>{
			return `<img id="${img.src==src?imgFocus:''}" src="${img.src}">`
		}).join("")
		let html = `<div>${imgStr}</div>`
		this.gallary.innerHTML = html
		if(src){
			let cimg=this.gallary.querySelector("#"+imgFocus)
			cimg&&setTimeout(()=>{
				cimg.scrollIntoViewIfNeeded()
				cimg.id=""
			})
		}

	}
	onBackMode(src){
		this.webPickMode = false
		this.webPickImgs()
		if(this.gallary.classList.contains(CN.withshow)){
			this.renderGallary(src)
		}

		this.$event.emit(EN.img_done,src)
		document.documentElement.classList.remove(this.cn.imgPicking)
	}
	onFocusOut(){
		this.actionBar.focusOut()
	}
	onFocusIn(){
		this.webPickImgs()
		this.actionBar.focusIn()
	}
	webPageImgToggleFocus(src){
		this.imgCache.forEach(img=>{
			img.classList[img.src===src?"add":"remove"](CN.imgFocus)
		})
	}
	webPickImgs(){
		let imgs = this.inViewportFilter()
		this.imgCache = [].filter.call(imgs,(img)=>{
			// let c1 = !(/gif$/i.test(img.src))
			let cms = window.getComputedStyle(img)
			let c1 = cms.visibility==="hidden"
			let c2 = cms.display==="none"
			let c3 = parseInt(cms.width)<50&&parseInt(cms.height)<50
			// let c4 = img.src.length>500
			
			return (!c1)&&(!c2)&&(!c3)
		})
	}
	scrollParent(dom){
		while(true){
			if(dom===document.documentElement)break
			dom = dom.parentElement
			if(dom.scrollHeight==0&&dom.scrollWidth==0)continue
			let c1 = dom.scrollHeight>dom.offsetHeight
			let c2 = dom.scrollWidth>dom.offsetWidth
			if(c1||c2)break
		}
		return dom
	}
	inViewportFilter(){
		let s = `img:not(.${this.cn.gallary} img)`
		let imgs = document.querySelectorAll(s)
			imgs = [].filter.call(imgs,img=>{
				return img.offsetWidth>0||img.offsetHeight>0
			})
			let {width,height} = document.pageRect()
			return [].filter.call(imgs,(img)=>{
				let {offsetHeight,
					offsetWidth,
					offsetTop,
					offsetLeft} = img
				let abso = this.absOffset(img)
				offsetLeft = abso.ol
				offsetTop = abso.ot
				let {st,sl} = this.absScrollRect(img)
				let c1 = offsetTop-st
				let c2 = offsetLeft-sl
				
				let c10 = c1>=-offsetHeight&&c1<=height&&c2>=-offsetWidth&&c2<=width

				let pe = this.scrollParent(img)
				let {ol,ot} = this.absOffset(pe)
				let rx = offsetLeft-ol-pe.scrollLeft
				let ry = offsetTop-ot-pe.scrollTop
				
				let c3 = rx>=-offsetWidth&&rx<=(pe.offsetWidth||pe.scrollWidth)
				let c4 = ry>=-offsetHeight&&ry<=(pe.offsetHeight||pe.scrollHeight)

				let c11 = c3&&c4
				return c10&&c11
			})
	}
	absOffset(dom){
		let ot = 0
		let ol = 0
		let body = document.body
		let {scrollLeft,scrollTop} = body
		while(true){
			if(dom===body)break
			if(!dom)break
			ot+=dom.offsetTop
			ol+=dom.offsetLeft
			dom = dom.offsetParent
		}
		return {ot,ol}
	}
	absScrollRect(dom){
		let st = 0
		let sl = 0
		let doc = document.documentElement
		let {scrollLeft,scrollTop} = doc
		while(true){
			if(dom===doc)break
			st+=dom.scrollTop
			sl+=dom.scrollLeft
			dom = dom.parentElement

		}
		st+=scrollTop
		sl+=scrollLeft
		return {
			st,sl
		}
	}
	inPath(pageX,pageY){
		let {scrollLeft,scrollTop} = document.documentElement;
		let inPath = [].filter.call(this.inViewportFilter(),(img)=>{
			let {x,y,width,height} = img.getBoundingClientRect()
			let ex = pageX - scrollLeft - x
			let ey = pageY - scrollTop - y
			return (ex>=0&&ex<=width)&&(ey>=0&&ey<=height) 
		})
		return inPath
	}
}